package com.zxq.uart.frame;

import com.zxq.factory.EncoderFactory;
import com.zxq.factory.FastFrame;
import com.zxq.factory.annotate.DecoderField;
import com.zxq.factory.annotate.EncoderField;
import com.zxq.factory.annotate.Frame;
import com.zxq.factory.enums.EField;
import com.zxq.factory.enums.ETrimMethod;
import com.zxq.memory.ByteCombination;
import lombok.Data;

@Data
@Frame
public class UartFrame<T> {

    /**
     * SOP：	单字节字头。命令为 ee，应答为66 。
     * LEN：	单字节。从CMD到SUM的字节数（含CMD和SUM）
     * CMD：
     * SESSION_ID：	单字节，命令字节。
     * 服务端回话编号，6个字节，用户服务端识别通讯会话。如果服务端发起的会话设备应答服务端需要带上服务端下发的会话ID。如果设备发起会话则会话ID为“000000”
     * DATA：	数据字节，不定长。
     * SUM：	单字节，LEN、CMD、SESSION_ID、DATA的异或值
     */
    // 66 0D 06 00000000 00000500000000 0E
    @EncoderField(sequence = 1,len = 1)
    @DecoderField(sequence = 1,param = 1)
    Integer sop = 0xee;
    @EncoderField(sequence = 2,len = 1)
    @DecoderField(sequence = 2,param = 1)
    Integer len;
    @EncoderField(sequence = 3,len = 1)
    @DecoderField(sequence = 3,param = 1)
    Integer cmd;

    @EncoderField(sequence = 4,len = 6,field = EField.Hex)
    @DecoderField(sequence = 4,param = 6,field = EField.Hex)
    String session_id;

    @EncoderField(sequence = 5,field = EField.Frame)
    @DecoderField(sequence = 5,field = EField.Frame,method = ETrimMethod.Tail,param = 1)
    T data;
    @EncoderField(sequence = 6,field = EField.Byte,len = 1)
    @DecoderField(sequence = 6,param = 1,field = EField.Byte)
    Byte sum;



    public byte[] encoder() {
        byte[] sopBuff =  EncoderFactory.encoderField(UartFrame.class,"sop",sop);
        byte[] dataBuff =  EncoderFactory.encoderField(UartFrame.class,"data",data);
        len = 1 + 6 + dataBuff.length + 1;
        byte[] frame = ByteCombination.combinationContent(FastFrame.encoder(this),dataBuff);
        byte flag = frame[0];
        for(int i = 1; i < frame.length; i++) {
            flag ^= frame[i];
        }
        sum = flag;
        byte[] sumBuff = EncoderFactory.encoderField(UartFrame.class,"sum",sum);
        //System.out.println("sum: " + HexBin.encode( sumBuff));
        byte[] total = ByteCombination.combinationContent(sopBuff,frame,sumBuff);
        return total;
    }



}
